using GrapeCity.Forguncy.Commands;
using GrapeCity.Forguncy.Log;
using GrapeCity.Forguncy.Plugin;
using Grpc.Core.Interceptors;
using Grpc.Net.Client;
using Qdrant.Client;
using Qdrant.Client.Grpc;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Threading.Tasks;

namespace QdrantConnector
{

    public abstract class BaseQdrantOp : Command, ICommandExecutableInServerSideAsync
    {

        public abstract override string ToString();

        [FormulaProperty]
        [DisplayName("服务器")]
        [OrderWeight(1)]
        public object HostExpr { get; set; }

        [FormulaProperty]
        [DisplayName("端口号")]
        [OrderWeight(2)]
        public object PortExpr { get; set; }

        [FormulaProperty]
        [DisplayName("密钥")]
        [OrderWeight(3)]
        public object APIKeyExpr { get; set; }

        [BoolProperty]
        [DisplayName("使用HTTPS")]
        [OrderWeight(4)]
        public bool ShouldUseHttps { get; set; }

        [FormulaProperty]
        [DisplayName("证书指纹（Thumbprint）")]
        [Description("如果使用HTTPS连接Qdrant服务器，需要提供证书指纹。")]
        [OrderWeight(5)]
        public object ThumbprintExpr { get; set; }

        [FormulaProperty]
        [DisplayName("集合名")]
        [OrderWeight(5)]
        public object NameExpr { get; set; }

        private QdrantClient _client;

        internal async Task<QdrantClient> getQrantClient(IServerCommandExecuteContext dataContext)
        {
            if (_client == null)
            {
                var host = (await dataContext.EvaluateFormulaAsync(this.HostExpr))?.ToString() ?? "localhost";
                var port = (await dataContext.EvaluateFormulaAsync(this.PortExpr))?.ToString() ?? "6334";
                var apiKey = (await dataContext.EvaluateFormulaAsync(this.APIKeyExpr))?.ToString() ?? null;
                var thumbprint = (await dataContext.EvaluateFormulaAsync(this.ThumbprintExpr))?.ToString() ?? null;


                if (ShouldUseHttps)
                {
                    var channel = GrpcChannel.ForAddress($"https://" + host + ":" + port, new GrpcChannelOptions
                    {
                        HttpHandler = new WinHttpHandler
                        {
                            ServerCertificateValidationCallback = CertificateValidation.Thumbprint(thumbprint)
                        }
                    });

                    var callInvoker = channel.Intercept(metadata =>
                    {
                        if (apiKey != null)
                        {
                            metadata.Add("api-key", apiKey);
                        }

                        return metadata;
                    });

                    var grpcClient = new QdrantGrpcClient(callInvoker);
                    _client = new QdrantClient(grpcClient);

                }
                else
                {
                    _client = new QdrantClient(host, int.Parse(port), apiKey: apiKey);
                }

            }

            return _client;
        }

        internal async Task<string> getCollectionName(IServerCommandExecuteContext dataContext)
        {
            return (await dataContext.EvaluateFormulaAsync(this.NameExpr))?.ToString() ?? "";
        }

        public abstract Task<ExecuteResult> ExecuteAsync(IServerCommandExecuteContext dataContext);

        public override CommandScope GetCommandScope()
        {
            return CommandScope.ExecutableInServer;
        }


    }
}
